package vip.xiaonuo.issued.impl;

import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import vip.xiaonuo.core.exception.ServiceException;
import vip.xiaonuo.core.factory.PageFactory;
import vip.xiaonuo.core.pojo.httpclient.ReturnJson;
import vip.xiaonuo.core.pojo.page.PageResult;
import vip.xiaonuo.facedoor.iservice.IDeviceBaseService;
import vip.xiaonuo.facedoor.iservice.IFaceDoorDtoService;
import vip.xiaonuo.facedoor.modular.devicebase.entity.DeviceBase;
import vip.xiaonuo.facedoor.modular.devicebase.param.DeviceBaseParam;
import vip.xiaonuo.facedoor.modular.devicebase.service.DeviceBaseService;
import vip.xiaonuo.facedoor.modular.deviceset.entity.DwDeviceSet;
import vip.xiaonuo.facedoor.modular.deviceset.service.DwDeviceSetService;
import vip.xiaonuo.facedoor.modular.memberdevice.entity.MemberDevice;
import vip.xiaonuo.facedoor.modular.memberdevice.service.MemberDeviceService;
import vip.xiaonuo.facedoor.modular.orgdevice.entity.OrgDevice;
import vip.xiaonuo.facedoor.modular.orgdevice.service.OrgDeviceService;
import vip.xiaonuo.facedoor.modular.visitordevice.entity.VisitorDevice;
import vip.xiaonuo.facedoor.modular.visitordevice.service.VisitorDeviceService;
import vip.xiaonuo.facedoor.remote.iservice.adapter.MemberReqAdapter;
import vip.xiaonuo.facedoor.rule.DwRulesEngine;
import vip.xiaonuo.facedoor.rule.RuleConstant;
import vip.xiaonuo.facedoor.vo.dewo.GetPersonRequest;
import vip.xiaonuo.facedoor.vo.dewo.GetPersonResponse;
import vip.xiaonuo.sys.modular.timer.param.SysTimersParam;
import vip.xiaonuo.sys.modular.timer.service.SysTimersService;
import vip.xiaonuo.sys.modular.timer.util.TaskUtil;

import java.util.ArrayList;
import java.util.Optional;

@Service(RuleConstant.DW+ RuleConstant.DEVICE_BASE)
public class HttpDeviceBaseService implements IDeviceBaseService {


  @Autowired
  private MemberReqAdapter personService;

  @Autowired
  private OrgDeviceService orgDeviceService;

  @Autowired
  private MemberDeviceService memberDeviceService;

  @Autowired
  private SysTimersService sysTimersService;

  @Autowired
  private VisitorDeviceService visitorDeviceService;

  @Autowired
  private DeviceBaseService deviceBaseService;


  @Autowired
  private DwDeviceSetService dwDeviceSetService;


  @Override
  public PageResult<GetPersonResponse.DataDTO.PersonnelListDTO> listPerson(Long deviceId,String name) {
    DeviceBase deviceBase = deviceBaseService.getById(deviceId);
    if (StringUtils.isEmpty(deviceBase.getCabinetIp()) || deviceBase.getCabinetPort() == null) {
      throw new ServiceException(500, "设备尚未配置ip和端口!");
    }
    String uri = IFaceDoorDtoService.getBaseParam(deviceBase.getCabinetIp(), Integer.parseInt(deviceBase.getCabinetPort()));
    Page<GetPersonResponse.DataDTO.PersonnelListDTO> objectPage = PageFactory.defaultPage();
    long current = objectPage.getCurrent();
    objectPage.setSize(10);
    GetPersonRequest getPersonRequest = new GetPersonRequest().setPage(current + "").setLimit(10 + "");
    if (StringUtils.isNotBlank(name)){
      getPersonRequest.setQueryType("3").setName(name);
    }else {
      getPersonRequest.setQueryType("2");
    }
    try {
      GetPersonResponse getPersonResponse = DwRulesEngine.faceDoorDtoService.listPerson(uri, getPersonRequest);
      if (getPersonResponse.getData()==null){
        return new PageResult<>(objectPage, new ArrayList<>());
      }
      objectPage.setTotal(Long.parseLong(Optional.ofNullable(getPersonResponse.getData().getTotalNum()).orElse(getPersonResponse.getData().getPersonnelList().size()+"")));
      return new PageResult<>(objectPage, getPersonResponse.getData().getPersonnelList());
    } catch (Exception e) {
      throw new ServiceException(500, "获取人员信息发生错误 错误信息【" + ExceptionUtils.getMessage(e) + "】");
    }
  }

  @Override
  public void delete(DeviceBaseParam deviceBaseParam) {
    DeviceBase deviceBase = deviceBaseService.getById(deviceBaseParam.getId());
    // 强制删除 不清空设备人员
    if ((deviceBase.getCabinetIp() == null || deviceBase.getCabinetPort() == null)
            || (deviceBaseParam.getMandatory() != null
            && ObjectUtil.equal(deviceBaseParam.getMandatory(), 1))) {
      deviceBaseService.removeById(deviceBaseParam.getId());
      orgDeviceService.remove(new LambdaQueryWrapper<OrgDevice>().eq(OrgDevice::getDeviceId, deviceBase.getId()));
      memberDeviceService.remove(new LambdaQueryWrapper<MemberDevice>().eq(MemberDevice::getDeviceId, deviceBase.getId()));
      visitorDeviceService.remove(new LambdaQueryWrapper<VisitorDevice>().eq(VisitorDevice::getDeviceId, deviceBase.getId()));
      dwDeviceSetService.remove(new LambdaQueryWrapper<DwDeviceSet>().eq(DwDeviceSet::getDeviceBaseId, deviceBase.getId()));
      if (!TaskUtil.executeXxlJob()) {
        // 定时任务删除
        SysTimersParam sysTimersParam = new SysTimersParam();
        sysTimersParam.setId(deviceBase.getTaskId());
        sysTimersService.delete(sysTimersParam);
      }
      return;
    }

    // 强制删除本地 不清空设备人员
    if ((deviceBase.getCabinetIp() == null || deviceBase.getCabinetPort() == null)
            || (deviceBaseParam.getMandatoryLocal() != null
            && ObjectUtil.equal(deviceBaseParam.getMandatoryLocal(), 1))) {
      try {
        String uri = IFaceDoorDtoService.getBaseParam(deviceBase.getCabinetIp(), Integer.parseInt(deviceBase.getCabinetPort()));
        ReturnJson returnJson = personService.deleteAllPerson(uri);
        if (returnJson.getCode().equals("0000")) {
          orgDeviceService.remove(new LambdaQueryWrapper<OrgDevice>().eq(OrgDevice::getDeviceId, deviceBase.getId()));
          memberDeviceService.remove(new LambdaQueryWrapper<MemberDevice>().eq(MemberDevice::getDeviceId, deviceBase.getId()));
          visitorDeviceService.remove(new LambdaQueryWrapper<VisitorDevice>().eq(VisitorDevice::getDeviceId, deviceBase.getId()));
        } else {
          throw new ServiceException(500, "删除设备失败 失败信息： code" + returnJson.getCode() + " message" + Optional.ofNullable(returnJson.getMsg()).orElse(""));
        }
      } catch (Exception e) {
        throw new ServiceException(500, "删除设备失败 失败信息：" + ExceptionUtil.getMessage(e));
      }
      return;
    }
    String uri = IFaceDoorDtoService.getBaseParam(deviceBase.getCabinetIp(), Integer.parseInt(deviceBase.getCabinetPort()));
    try {
      ReturnJson returnJson = personService.deleteAllPerson(uri);
      if (returnJson.getCode().equals("0000")) {
        deviceBaseService.removeById(deviceBaseParam.getId());
        orgDeviceService.remove(new LambdaQueryWrapper<OrgDevice>().eq(OrgDevice::getDeviceId, deviceBase.getId()));
        memberDeviceService.remove(new LambdaQueryWrapper<MemberDevice>().eq(MemberDevice::getDeviceId, deviceBase.getId()));
        visitorDeviceService.remove(new LambdaQueryWrapper<VisitorDevice>().eq(VisitorDevice::getDeviceId, deviceBase.getId()));
        dwDeviceSetService.remove(new LambdaQueryWrapper<DwDeviceSet>().eq(DwDeviceSet::getDeviceBaseId, deviceBase.getId()));
        if (!TaskUtil.executeXxlJob()) {
          // 定时任务删除
          SysTimersParam sysTimersParam = new SysTimersParam();
          sysTimersParam.setId(deviceBase.getTaskId());
          sysTimersService.delete(sysTimersParam);
        }
      } else {
        throw new ServiceException(500, "删除设备失败 失败信息： code" + returnJson.getCode() + " message" + Optional.ofNullable(returnJson.getMsg()).orElse(""));
      }
    } catch (Exception e) {
      throw new ServiceException(500, "删除设备失败 失败信息：" + ExceptionUtil.getMessage(e));
    }
  }

  @Override
  public void setUserPwd(DeviceBaseParam deviceBaseParam) {

  }

  @Override
  public void setFactoryDefault(DeviceBaseParam deviceBaseParam) {

  }

  @Override
  public void setSysTime(DeviceBaseParam deviceBaseParam) {

  }

  @Override
  public void openDoor(DeviceBaseParam deviceBaseParam) {

  }
}
